﻿using System;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Collections.Generic;
//using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Resources;
using System.Windows.Controls;


namespace uhul.Controls
{


  public partial class AppLoader : UserControl
  {


    private InteractiveApp _app;

    public AppLoader()
    {
      InitializeComponent();
    }





    //public AppInfo AppInfo
    //{ get; private set; }





    public void LoadApp(InteractiveApp app)
    {

      _app = app;

      this.LoadMsgs.Text = "startuji aplikaci";
      //this.AppIsBusy.IsBusy = true;

      //begin wait
      XapExplorer.Commands.Add(
        new Command()
        {
          CommandType = CommandTypeEnum.BeginWait
        }.ToJson()
      );

      //http://weblogs.asp.net/razan/archive/2010/01/14/emulating-synchronous-web-service-call-in-silverlight.aspx
      //AppViewportControl.Children.
      //UserControl currentPage = PageContainer.Children[0] as UserControl;
      //if (currentPage != page3) PageContainer.Children[0] = page3;

      WebClient client = new WebClient();
      client.OpenReadCompleted += new OpenReadCompletedEventHandler(xapLoad_OpenReadCompleted);
      try
      {
        client.OpenReadAsync(_app.AppInfo.XapUri);
      }
      catch (Exception e)
      {
        this.LoadMsgs.Text = "stahovani aplikace selhalo, chyba:" + e.Message;
        //this.AppIsBusy.IsBusy = false;

        //end wait
        XapExplorer.Commands.Add(
          new Command()
          {
            CommandType = CommandTypeEnum.EndWait
          }.ToJson()
        );
      }
    }





    private void xapLoad_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {

      WebClient w = (WebClient)sender;

      if (e.Error != null)
      {
        this.LoadMsgs.Text = "stahovani aplikace selhalo, chyba:" + e.Error.Message;
        //this.AppIsBusy.IsBusy = false;
        XapExplorer.Commands.Add(
          new Command()
          {
            CommandType = CommandTypeEnum.EndWait
          }.ToJson()
        );
        return;
      }

      Dictionary<string, Assembly> asms = _loadAllAssemblies(e.Result);
      UserControl uc = asms[_app.AppInfo.AssemblyName].CreateInstance(_app.AppInfo.UserControlName) as UserControl;

      //StreamResourceInfo sri4dll = Application.GetResourceStream(new StreamResourceInfo(e.Result, null),
      //                                  new Uri(_app.AppInfo.AssemblyName, UriKind.Relative));
      //AssemblyPart asmPart = new AssemblyPart();
      //Assembly asm = asmPart.Load(sri4dll.Stream);
      //UserControl uc = asm.CreateInstance(_app.AppInfo.UserControlName) as UserControl;

      //save AppInfo into new UC
      //uc.Resources.Add("AppInfo", _app.AppInfo);

      //hide loader...
      this.Visibility = System.Windows.Visibility.Collapsed;
      //remove loader...
      XapExplorer.AppViewportControl.Children.Remove(this);

      ////add app info Dictionary to new app
      if (!uc.Resources.Contains("uhul_eAgri_Environment"))
        uc.Resources.Add("uhul_eAgri_Environment", XapExplorer.Environment);

      if (!uc.Resources.Contains("uhul_eAgri_Commands"))
        uc.Resources.Add("uhul_eAgri_Commands", XapExplorer.Commands);

      if (!uc.Resources.Contains("uhul_eAgri_AppName"))
        uc.Resources.Add("uhul_eAgri_AppName", _app.AppInfo.Name);

      //uc.Resources.Add("uhul_eAgri_Environment", XapExplorer.Environment);
      //uc.Resources["uhul_eAgri_Commands"] = XapExplorer.Environment;

      //resolve Webservice entry points when available...
      if (!uc.Resources.Contains("ApplicationWebserviceEntryPoints")
        && _app.AppInfo.WebServiceEntryPoints != null
      )
        uc.Resources.Add("ApplicationWebserviceEntryPoints", _app.AppInfo.WebServiceEntryPoints);

      //resolve visibility for loaded control...
      uc.Visibility = this.Visibility;

      //add app user control
      XapExplorer.AppViewportControl.Children.Add(uc);
      //set usercontrol as application
      _app.Application = uc;

      //end wait
      XapExplorer.Commands.Add(
        new Command()
        {
          CommandType = CommandTypeEnum.EndWait
        }.ToJson()
      );

      //if (XapExplorer.ActiveApplication != null)
      //if (XapExplorer.ActiveApplication.Equals(this._app))
      //  uc.Focus();

    }





    private Dictionary<string, Assembly> _loadAllAssemblies(Stream s)
    {

      Dictionary<string, Assembly> tmp = new Dictionary<string, Assembly>();

      var manifestStream = Application.GetResourceStream(
          new StreamResourceInfo(s, null),
          new Uri("AppManifest.xaml", UriKind.Relative));

      string appManifest = new StreamReader(manifestStream.Stream).ReadToEnd();
      //string assemblyName = m_rootAssembly + ".dll";
      XmlReader reader = XmlReader.Create(new StringReader(appManifest));
      Assembly asm = null;
      while (reader.Read())
      {
        if (reader.IsStartElement("AssemblyPart"))
        {
          reader.MoveToAttribute("Source");
          reader.ReadAttributeValue();
          //if (reader.Value == assemblyName)
          //{
          var assemblyStream = new StreamResourceInfo(s, "application/binary");
          var si = Application.GetResourceStream(assemblyStream, new Uri(reader.Value, UriKind.Relative));
          AssemblyPart p = new AssemblyPart();
          
          asm = p.Load(si.Stream);
          tmp.Add(reader.Value, asm);
          //AppDomain.CurrentDomain.
          //break;
          //}
        }
      }

      return tmp;
    }



  }

}
